package com.telecom.sxint.app.core.service.impl.Pictureimpl;
import cn.hutool.core.util.StrUtil;
import cn.zjtele.pubinfo.boot.redis.config.RedisHelper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.telecom.sxint.app.core.domain.entity.Picturepojo.App1Picturemanagement;
import com.telecom.sxint.app.core.mapper.Picturemapper.App1PicturemanagementMapper;
import com.telecom.sxint.app.core.service.Pictureservice.IApp1PicturemanagementService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.io.FilenameUtils;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import cn.hutool.core.collection.CollUtil;
import cn.zjtele.pubinfo.common.http.response.ResponseData;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.telecom.sxint.app.core.domain.entity.Engineerpojo.App1Employeehours;
import com.telecom.sxint.app.core.domain.entity.Picturepojo.App1Picturemanagement;
import com.telecom.sxint.app.core.domain.entity.Query.PageData;
import com.telecom.sxint.app.core.domain.entity.dto.PictureQueryDTO;
import com.telecom.sxint.app.core.mapper.Picturemapper.App1PicturemanagementMapper;
import com.telecom.sxint.app.core.service.Pictureservice.IApp1PicturemanagementService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;

import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;

/**
 * <p>
 * 事件管理信息表 服务实现类
 * </p>
 *
 * @author
 * @since 2024-08-23
 */
@Service
public class App1PicturemanagementServiceImpl extends ServiceImpl<App1PicturemanagementMapper, App1Picturemanagement> implements IApp1PicturemanagementService {

     @Autowired
     private App1PicturemanagementMapper app1PicturemanagementMapper;
    @Autowired
    private RedisHelper redisHelper;
     /**
      * 新增图片数据
      * @param app1Picturemanagement
      * @return
     */
     @Override
     public ResponseData<App1Picturemanagement> insertPicture(App1Picturemanagement app1Picturemanagement) {
         redisHelper.deletePattern("picture:*");
         List<App1Picturemanagement>result=app1PicturemanagementMapper.selectList(null);
         String cacheKey = "picture:result"+result;
         app1PicturemanagementMapper.insert(app1Picturemanagement);
         redisHelper.valueSet(cacheKey, result, 3600L, TimeUnit.SECONDS);
         return ResponseData.success(app1Picturemanagement);
     }

    /**
     * 新增多个图片数据
     * @param app1Picturemanagements
     * @return
     */
    @Override
    public ResponseData<List<App1Picturemanagement>> insertPictures(List<App1Picturemanagement> app1Picturemanagements) {
        redisHelper.deletePattern("picture:*");
        List<App1Picturemanagement>result=app1PicturemanagementMapper.selectList(null);
        String cacheKey = "picture:result"+result;
        app1PicturemanagementMapper.insertBatch(app1Picturemanagements);
        redisHelper.valueSet(cacheKey, result, 3600L, TimeUnit.SECONDS);
        return ResponseData.success(result);
    }

    /**
     * 根据事件类型分页查询图片
     * @param pictureQueryDTO
     * @return
     */
    @Override
    public PageData queryPicturePageByEvent(PictureQueryDTO pictureQueryDTO,String event) {
        Page<App1Picturemanagement> page = Page.of(pictureQueryDTO.getCurrentPage(), pictureQueryDTO.getPageSize());
        //排序  page.addOrder(new OrderItem(ticketQueryDTO.))
        //2分页查询
        Page<App1Picturemanagement> p = lambdaQuery()
                .eq(App1Picturemanagement::getEvent, event)
                .eq(App1Picturemanagement::getIsDelete, 0) // 确保只查询 is_delete 字段为 0 的记录
                .page(page);
        //3封装VO结果
        PageData<App1Picturemanagement> dto = new PageData<>();
        //总条数
        dto.setTotal(p.getTotal());
        //当前页
        dto.setCurrentPage(p.getCurrent());
        //当前页数条数
        dto.setPageSize(p.getSize());
        //当前页数据
        List<App1Picturemanagement> records = p.getRecords();
        dto.setRecords(records);
        //4返回
        return dto;
    }
    /**
     * 根据事件类型查询图片
     */
    @Override
    public ResponseData<List<App1Picturemanagement>> getPictureByEvent(String event) {
        String cacheKey = "picture:" + event;
        List<App1Picturemanagement> cachedData = (List<App1Picturemanagement>) redisHelper.valueGet(cacheKey);
        if (cachedData != null) {
            return ResponseData.success(cachedData);
        }
        QueryWrapper<App1Picturemanagement> queryWrapper = new QueryWrapper<>();
        if(StrUtil.isEmpty(event)){
            queryWrapper.eq("is_delete",0)
                    .orderByAsc("event_time");
        }else {
            queryWrapper.eq("event", event)
                    .eq("is_delete",0)
                    .orderByAsc("event_time");
        }
        List<App1Picturemanagement> app1Picturemanagements = app1PicturemanagementMapper.selectList(queryWrapper);
        if (CollUtil.isEmpty(app1Picturemanagements)) {
            return ResponseData.failed("没有搜索到相关图片", "41008");
        }
        redisHelper.valueSet(cacheKey, app1Picturemanagements, 3600L, TimeUnit.SECONDS);
        return ResponseData.success(app1Picturemanagements);
    }
    /**
     * 根据id修改图片数据
     * @param app1Picturemanagement
     * @return
     */
    @Override
    public ResponseData<App1Picturemanagement> updatePicture(App1Picturemanagement app1Picturemanagement) {
        redisHelper.deletePattern("picture:*");
        app1PicturemanagementMapper.update(app1Picturemanagement, new UpdateWrapper<App1Picturemanagement>().eq("id", app1Picturemanagement.getId()));
        App1Picturemanagement app1Picturemanagement1 = app1PicturemanagementMapper.selectById(app1Picturemanagement.getId());

        return ResponseData.success(app1Picturemanagement1);
    }
    /**
     * 搜索图片、关键词搜索
     * @param key
     * @return
     */
    @Override
    public ResponseData<List<App1Picturemanagement>> getPictureByKey(String key) {
        QueryWrapper<App1Picturemanagement> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .eq("is_delete",0)
                .like("event_name", key)
                .or()
                .like("event_location", key)
                .or()
                .like("tags", key)
                .or()
                .like("main_personnel", key)
                .or()
                .like("department", key)
                .or()
                .like("event_type", key)
                .orderByAsc("event_time");
        List<App1Picturemanagement> app1Picturemanagements = app1PicturemanagementMapper.selectList(queryWrapper);
        if (CollUtil.isEmpty(app1Picturemanagements)) {
            return ResponseData.failed("没有搜索到相关图片", "41008");
        }
        return ResponseData.success(app1Picturemanagements);
    }
    /**
     * 分页条件查询
     * @param pictureQueryDTO
     * @return
     */
    @Override
    public PageData queryPicturePage(PictureQueryDTO pictureQueryDTO) {
//        String cacheKey = "picture:" + pictureQueryDTO.getCurrentPage() + ":" + pictureQueryDTO.getPageSize();
//        PageData cachedData = redisHelper.valueGet(cacheKey);
//        if (cachedData != null) {
//            return cachedData;
//        }
        Page<App1Picturemanagement> page = Page.of(pictureQueryDTO.getCurrentPage(), pictureQueryDTO.getPageSize());
        //排序  page.addOrder(new OrderItem(ticketQueryDTO.))
        //2分页查询
        Page<App1Picturemanagement> p = lambdaQuery()
                .eq(App1Picturemanagement::getIsDelete, 0) // 确保只查询 is_delete 字段为 0 的记录
                .page(page);
        //3封装VO结果
        PageData<App1Picturemanagement> dto = new PageData<>();
        //总条数
        dto.setTotal(p.getTotal());
        //当前页
        dto.setCurrentPage(p.getCurrent());
        dto.setPageSize(p.getSize());
        //当前页数据
        List<App1Picturemanagement> records = p.getRecords();
        dto.setRecords(records);
//        redisHelper.valueSet(cacheKey, dto, 3600L, TimeUnit.SECONDS);
        //4返回
        return dto;
    }

    /**
     * 分页查询
     * @param pictureQueryDTO
     * @return
     */
    @Override
    public PageData<App1Picturemanagement> queryAllPicturesPage(PictureQueryDTO pictureQueryDTO) {
        // 使用 MyBatis-Plus 的 Page 来处理分页
        Page<App1Picturemanagement> page = new Page<>(pictureQueryDTO.getCurrentPage(), pictureQueryDTO.getPageSize());  // 使用 `getCurrentPage()` 和 `getPageSize()`

        // 构建查询条件，这里没有过滤条件，只是查询所有图片
        QueryWrapper<App1Picturemanagement> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("is_delete", 0);  // 确保只查询没有被删除的记录

        // 如果需要支持排序，可以在这里加入排序条件
        queryWrapper.orderByDesc("event_time");  // 按照事件时间倒序排列

        // 执行分页查询
        IPage<App1Picturemanagement> iPage = app1PicturemanagementMapper.selectPage(page, queryWrapper);

        // 将查询结果封装到 PageData 对象中
        PageData<App1Picturemanagement> pageData = new PageData<>();
        pageData.setTotal(iPage.getTotal());
        pageData.setRecords(iPage.getRecords());
        pageData.setCurrentPage(pictureQueryDTO.getCurrentPage());  // 当前页
        pageData.setPageSize(pictureQueryDTO.getPageSize());    // 每页数据量

        return pageData;
    }
    /**
     *
     * @param imageFile
     * @return
     */

    private final long MAX_FILE_SIZE = 5 * 1024 * 1024; // 5 MB
    private final String[] SUPPORTED_FILE_TYPES = {"jpg", "jpeg", "png", "gif"};
    private final String EXTERNAL_API_URL = "http://172.26.7.151:96/api/sxint-sys/file/uploadMulti"; // Moved to a constant
    public ResponseData uploadImage(MultipartFile imageFile) throws IOException, InvalidFileTypeException, FileSizeLimitExceededException {
        // Validate file type using Apache Commons IO for robustness
        String fileExtension = FilenameUtils.getExtension(imageFile.getOriginalFilename()).toLowerCase();
        if (!Arrays.asList(SUPPORTED_FILE_TYPES).contains(fileExtension)) {
            throw new InvalidFileTypeException("不支持文件类型: " + fileExtension);
        }

        // Validate file size
        if (imageFile.getSize() > MAX_FILE_SIZE) {
            return uploadCompressedImage(imageFile);
        } else {
            return uploadImage1(imageFile);
        }
    }




    ResponseData uploadImage1(MultipartFile imageFile) throws IOException {
        return uploadToExternalApi(new ByteArrayResource(imageFile.getBytes()) {
            @Override
            public String getFilename() {
                return imageFile.getOriginalFilename();
            }
        });
    }

    private ResponseData uploadCompressedImage(MultipartFile imageFile) throws IOException {
        try (InputStream inputStream = imageFile.getInputStream()) {
            BufferedImage originalImage = ImageIO.read(inputStream);
            BufferedImage compressedImage = compressImage(originalImage, 0.5f); // Adjust compression ratio as needed

            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ImageIO.write(compressedImage, "jpg", baos); // Always save as JPG for consistency
            byte[] compressedImageBytes = baos.toByteArray();

            return uploadToExternalApi(new ByteArrayResource(compressedImageBytes) {
                @Override
                public String getFilename() {
                    return FilenameUtils.getBaseName(imageFile.getOriginalFilename()) + ".jpg";
                }
            });
        }
    }


    private BufferedImage compressImage(BufferedImage originalImage, float compressionRatio) {
        int newWidth = (int) (originalImage.getWidth() * compressionRatio);
        int newHeight = (int) (originalImage.getHeight() * compressionRatio);
        BufferedImage compressedImage = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB); // Use TYPE_INT_RGB for better compatibility
        Graphics2D g = compressedImage.createGraphics();
        g.drawImage(originalImage, 0, 0, newWidth, newHeight, null);
        g.dispose();
        return compressedImage;
    }

    private ResponseData uploadToExternalApi(ByteArrayResource fileResource) {
        RestTemplate restTemplate = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);

        MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
        body.add("file", fileResource);

        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);
        ResponseEntity<ResponseData> responseEntity = restTemplate.exchange(EXTERNAL_API_URL, HttpMethod.POST, requestEntity, ResponseData.class);

        if (responseEntity.getStatusCode() != HttpStatus.OK) {
            // Handle errors appropriately, log the error, throw an exception, etc.
            throw new RuntimeException("接口上传失败: " + responseEntity.getStatusCode());
        }
        return responseEntity.getBody();
    }

public class InvalidFileTypeException extends RuntimeException {
    public InvalidFileTypeException(String message) {
        super(message);
    }
}

public class FileSizeLimitExceededException extends RuntimeException {
    public FileSizeLimitExceededException(String message) {
        super(message);
    }
}

    /**上传图片或视频
     *
     * @param file
     * @return
     */
    @Override
    public ResponseData uploadFile(MultipartFile file) {
        redisHelper.deletePattern("picture:*");

        try {
            String fileName = file.getOriginalFilename();
            String fileType = fileName.substring(fileName.lastIndexOf(".") + 1);

            // 检查文件类型是否为图片或视频
            if (!isSupportedFileType(fileType)) {
                return ResponseData.failed("不支持文件类型","41006");
            }


            if (!file.isEmpty()) {

                // TODO 定义文件存储路径
                // 定义文件存储路径
                String folderPath = "C:\\image\\";
                File folder = new File(folderPath);
                // 检查文件夹是否存在，如果不存在则创建
                if (!folder.exists()) {
                    folder.mkdirs(); // 创建文件夹及其所有必需的父文件夹
                }
                String path = folderPath + fileName;
                // 创建File对象
                File destFile = new File(path);
                // 将上传的文件转换为File对象并存储
                file.transferTo(destFile);
                // 返回文件存储路径
                System.out.println(destFile.getAbsolutePath());
                String filePath = destFile.getAbsolutePath();

                // 生成文件链接
                String mediaUrl = path;
                HashMap<Object, Object> map = new HashMap<>();
                map.put("Link",mediaUrl);
                // 存储文件链接到数据库
                return ResponseData.success(map);
            } else {
                throw new RuntimeException("您上传的文件为空，请选择文件后重试！");
            }

        } catch (Exception e) {
            return ResponseData.failed("图片上传失败","41006");
        }
    }


    private boolean isSupportedFileType(String fileType) {
        // 支持的文件类型列表
        List<String> supportedTypes = Arrays.asList("jpg", "jpeg", "png", "gif", "mp4", "mov");
        return supportedTypes.contains(fileType.toLowerCase());
    }

}
